<?php
/**
 * 文件上传处理模型
 *
 * ============================================================================
 * 版权所有: (c) 2009-2011，<UEShop Inc>，并保留所有权利。
 * 网站地址: http://www.ueshop.cn
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 * @author cmpan
 * @copyright   Copyright (c) 2009-2011 UEShop Inc. (http://www.ueshop.cn)
 * @license     http://www.ueshop.cn/1_0.txt
 */
class UploaderModel extends UE_Model {
	public $table         = 'ue_upload';
	public $key           = 'upload_id';
	protected $_field         = 'file';
	protected $_allowTypes    = '';  // 留空，如果不赋值则会从配置中载入
	
	protected $_allowImages   = array();
	protected $_allowVideos   = array();
	protected $_allowAudios   = array();
	
	protected $_isNewUpload   = false;  // 新上传
	
	public $thumbWidth;
	public $thumbHeight;
	
	/**
	 * 是否启用水印
	 *
	 * @var bool
	 */
	public $imgWatermark      = true;
	
	public function __construct() {
		$this->thumbWidth = UE_Config::get('thumb_width');
		$this->thumbHeight = UE_Config::get('thumb_height');		
		UE_Lang::add('upload');
	}	
	
	/**
	 * 设置上传的文件域的名称
	 *
	 * @param string $field
	 * @return UploadModel
	 */
	public function setField($field) {
		$this->_field = $field;
		return $this;
	}
	
	/**
	 * 设置允许上传的文件
	 *
	 * @param string $types 后缀名用|隔开，比如： zip|rar|doc
	 * @return UploadModel
	 */
	public function setAllowTypes($types) {
		$this->_allowTypes = trim($types);
		return $this;
	}


	/**
	 * 添加新的附件
	 *
	 * @param array $data 新附件信息
	 * @return array|false 添加成功后的完整附件信息
	 */
	public function add($data) {
		if (empty($_FILES)) {
		    $this->setErr('请检查您的表单enctype。');
			return false;
		}
		file_put_contents(SITE_DIR.'/test.php', date('Y-m-d H:i:s '). var_export($_FILES, 1));
		$rData = $this->_uploadHandle($data);
		
		if ($rData) {				
			$rData['upload_id'] = parent::add($rData);
		}
		
		if (empty($rData['upload_id'])) {
			return false;
		}
		
		return $rData;
	}
	
	/**
	 * 是否是允许上传的文件类型
	 * 
	 * @todo 通过mime来判断文件为是否允许上传类型
	 * @param string $sExt 文件扩展名
	 * @return bool
	 */
	public function isAllowType($sExt) {
		$sExt = trim($sExt, '. ');  // 去掉前后的点号和空格
		// 系统设置的当前文件允许上传文件类型串		
		if (!$this->_allowTypes) {
			$this->_allowTypes = OptionModel::getOption('ALLOW_UPLOAD_TYPE') . '|'
			                    .OptionModel::getOption('ALLOW_IMAGE_TYPE') . '|'
			                    .OptionModel::getOption('ALLOW_VIDEO_TYPE') . '|'
			                    .OptionModel::getOption('ALLOW_AUDIO_TYPE');
		    $this->_allowTypes = str_replace(array(' ', '||'), array('', '|'), $this->_allowTypes);
		}
		
		$aAllowUploadType = explode('|', $this->_allowTypes);
		$aAllowUploadType = array_map('trim', $aAllowUploadType);  // 去掉从配置中来的空格
		
		return in_array(strtolower($sExt), $aAllowUploadType) ? true : false;
	}
	
	/**
	 * 更新附件
	 *
	 * @param array $data 要更新的附近字段信息
	 * @return array|bool 更新后的附件信息,如果更新失败则返回false
	 */
	public function update($data) {
		if (!empty($_FILES[$this->_field]['tmp_name']) && !$this->_isNewUpload) {
			// 文件更新
			is_file(SITE_DIR . '/' . $data['upload_path']) && @unlink(SITE_DIR . '/' . $data['upload_path']);
			
			$data = $this->_upload($data);
		}
		
		if(parent::update($data)) {
			return $data;
		} else {
			return false;
		}
	}
	
	/**
	 * 处理文件上传
	 *
	 * @param array $data 文件信息
	 * @return array 上传文件信息
	 */
	protected function _uploadHandle(&$data) {
		set_time_limit(0);
		
		$msgs[UPLOAD_ERR_OK]           = UE_Lang::get('upload.err.ok');
		$msgs[UPLOAD_ERR_INI_SIZE]     = UE_Lang::get('upload.err.ini.size');
		$msgs[UPLOAD_ERR_FORM_SIZE]    = UE_Lang::get('upload.err.form.size');
		$msgs[UPLOAD_ERR_PARTIAL]      = UE_Lang::get('upload.err.partial');
		$msgs[UPLOAD_ERR_NO_FILE]      = UE_Lang::get('upload.err.no.file');
		$msgs[UPLOAD_ERR_NO_TMP_DIR]   = UE_Lang::get('upload.err.no.tmp.dir');
		$msgs[UPLOAD_ERR_CANT_WRITE]   = UE_Lang::get('upload.err.cant.write');
		
		// 验证文件类型	
		$tmpFile   = &$_FILES[$this->_field]["tmp_name"];
        $fileName  = &$_FILES[$this->_field]['name'];
        $error     = &$_FILES[$this->_field]["error"];     
		$suffix    = trim(substr($fileName, strrpos($fileName, '.') + 1));
		
		// 不允许上传没有后缀的文件
		if (empty($suffix)) {
			$this->setErr(UE_Lang::get('upload.noext.denied'));			
			return false;
		}
		
		$uploadDir = '';
		if ('Y' == UE_Config::get('upload_archive_time')) {
			$uploadDir = UPLOAD_DIR . '/' . date('Y');
		} else if ('M' == UE_Config::get('upload_archive_time')) {
			$uploadDir = UPLOAD_DIR . '/' . date('Y/m');
		} else if ('D' == UE_Config::get('upload_archive_time')) {
			$uploadDir = UPLOAD_DIR . '/' . date('Y/m/d');
		}
		
        $distFile = $uploadDir . '/' . realUniqid() . '.' . $suffix;
        
		if (!is_file(dirname($distFile))) {
			mkdir(dirname($distFile), 0755, true);
		}
		
		// TODO文件大小限制
		
		if ($error != UPLOAD_ERR_OK) {
			$this->setErr($msgs[$error]);
			return false;
		}
		
		//检查上传文件的类型
		if ($fileName == $suffix || !$this->isAllowType($suffix)) {
			$this->setErr(UE_Lang::get('upload.denied.type').', '.UE_Lang::get('upload.allow.type.is'). $this->_allowTypes);
			return false;
		}
		
		if (!is_uploaded_file($tmpFile)) {
			$this->setErr(UE_Lang::get('upload.file.has.err'));			
			return false;
		}        
		
		if(!move_uploaded_file($tmpFile, $distFile)) {
			$this->setErr(UE_Lang::get('upload.file.move.err'));
			return false;
		}
		
		// 图片水印
		if (in_array(strtolower($suffix), array('jpg', 'gif', 'png'))) {
			if (UE_Config::get('is_use_watermark') && $this->imgWatermark) {
				$image = new UE_Image($distFile);
				// 打水印
				$image->watermark(UE_Config::get('watermark_image'), UE_Config::get('watermark_position'), UE_Config::get('watermark_quality'));
			}
		}
		
		if (empty($data['upload_name'])) {
			$data['upload_name'] = addslashes($fileName);
		}
		
		list($fileType) = explode('/', $_FILES[$this->_field]['type']);
				
		$data['upload_path']           = substr($distFile, strlen(SITE_DIR) + 1);  // uploads/xxx/xxx.xx
		$data['upload_dateline']       = time();
		$data['user_id']               = &$_SESSION['user_id'];
		$data['upload_md5']            = md5_file($distFile);
		$data['upload_mime']           = &$_FILES[$this->_field]['type'];
		$data['upload_is_image']       = $fileType == 'image' ? 1 : 0;
		$data['upload_is_audio']       = $fileType == 'audio' ? 1 : 0;
		$data['upload_is_video']       = $fileType == 'video' ? 1 : 0;
		$data['upload_is_flash']       = $_FILES[$this->_field]['type'] == 'application/x-shockwave-flash' ? 1 : 0;
		$data['upload_size']           = &$_FILES[$this->_field]['size'];
		
		// swfupload fix
		if ('application/octet-stream' == $_FILES[$this->_field]['type']  
		      && !$data['upload_is_image'] && !$data['upload_is_audio'] && !$data['upload_is_video']) {
		    $allowImagesTypes = OptionModel::getOption('ALLOW_IMAGE_TYPE');	    
			$allowImagesTypes = explode('|', $allowImagesTypes);
			$allowImagesTypes = array_map('trim', $allowImagesTypes);
			
		    if (in_array(strtolower($suffix), $allowImagesTypes)) {				    	
				$data['upload_is_image'] = 1;				
		    } elseif (strtolower($suffix) == 'swf') {
		    	$data['upload_is_flash'] = 1;
		    } else {
		    	$allowVideosTypes = OptionModel::getOption('ALLOW_VIDEO_TYPE');	    
			    $allowVideosTypes = explode('|', $allowVideosTypes);
			    $allowVideosTypes = array_map('trim', $allowVideosTypes);
		    	if (in_array(strtolower($suffix), $allowVideosTypes)) {				    	
					$data['upload_is_video'] = 1;				
			    } else {
			    	$allowAudiosTypes = OptionModel::getOption('ALLOW_AUDIO_TYPE');	    
				    $allowAudiosTypes = explode('|', $allowAudiosTypes);
				    $allowAudiosTypes = array_map('trim', $allowAudiosTypes);
			    	if (in_array(strtolower($suffix), $allowAudiosTypes)) {				    	
						$data['upload_is_audio'] = 1;				
				    } 
			    }
		    }
		}
		
		return $data;
	}
	
	public function delete() {
		$file = $this->read();
		$dist = SITE_DIR . '/' . $file['upload_path'];
		is_file($dist) && unlink($dist);
		is_file($dist . '.thumb.jpg') && unlink($dist . '.thumb.jpg');
						
		return parent::delete();
	}
	
	/**
	 * 获取附件
	 *
	 * @param int $offset 分页下标，从第几个开始
	 * @param int $limit  每页显示多少个
	 * @param string $type video|audio
	 */
	public function getUploads($offset = 0, $limit = 20, $type = '') {
		$sql = "SELECT * FROM {$this->_table} t LEFT JOIN UE_users u ON t.user_id = u.user_id ";
		if ($type && $type =='video') {
			$sql .= " WHERE upload_is_video='1' ";
		} elseif ($type && $type =='audio') {
			$sql .= " WHERE upload_is_audio='1' ";
		}
		$sql .= " ORDER BY upload_id DESC LIMIT $offset, $limit";
		
		return UE_DB::factory()->getAll($sql);
	}
}
